package com.lottery.service.qiuqiu.accoutService;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.lottery.dao.qiuqiu.accoutDao.CustomerServiceDao;
import com.lottery.dao.qiuqiu.accoutDao.ManualCustomerDao;
import com.lottery.dao.qiuqiu.accoutDao.UserDao;
import com.lottery.dao.qiuqiu.bettingDao.BettingLimitationDao;
import com.lottery.dao.qiuqiu.lobbyDao.BettinginfoDao;
import com.lottery.dao.qiuqiu.lobbyDao.NoticeDao;
import com.lottery.dao.qiuqiu.statisticsDao.AgencyDao;
import com.lottery.dao.qiuqiu.wealthDao.AccountDao;
import com.lottery.dao.qiuqiu.wealthDao.AccountTransactionDao;
import com.lottery.dto.AccountTransactionDto;
import com.lottery.dto.UtilsDto;
import com.lottery.entity.*;
import com.lottery.initData.InitData;
import com.lottery.service.qiuqiu.JedisClient;
import com.lottery.service.qiuqiu.wealthService.WithdrawalsService;
import com.lottery.utils.CustomerContext;
import com.lottery.utils.DateUtil;
import com.lottery.utils.DealWithDouble;
import com.lottery.utils.RandCodeUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class ManualCustomerService {

    @Autowired
    private ManualCustomerDao manualcustomerDao;

    @Autowired
    private BettinginfoDao bettinginfoDao;

    // @Autowired
    private CustomerContext customerContext;

    @Autowired
    private JedisClient jedisClient;

    @Autowired
    private UserDao userdao;

    @Autowired
    private AgencyDao agencydao;

    @Autowired
    private AccountDao accountdao;

    @Autowired
    private CustomerServiceDao customerdao;

    @Autowired
    private NoticeDao noticeDao;

    @Autowired
    private AccountTransactionDao accounttransactionDao;

    @Autowired
    private BettingLimitationDao bettinglimitationDao;

    @Resource
    public WithdrawalsService withdrawalsService;

    public static Map<Integer, Integer> onlineMap = new ConcurrentHashMap<Integer, Integer>();

    // #生成的手机短信验证码以 key的 形式存储
    @Value("${LOGINSYSTEM1}")
    private String LOGINSYSTEM1;

    @Value("${AUTOCASH}")
    private String AUTOCASH;

    @Value("${LIMITAUTOCASH}")
    private String LIMITAUTOCASH;

    @Value("${HOSTADDR}")
    private String HOSTADDR;

    @Autowired
    private AccountTransactionDao accounttransactiondao;

    // 日志
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    // 客户发送消息

    public String userSendMsg(int srcId, int dstId, String message) {
        // 日志
        logger.info("userSendMsg in:{},{},{}", srcId, dstId, message);

        Map<String, Object> maxmap = new HashMap<String, Object>();
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        try {
            // 先发送者会发送消息给接受者通过接受者的 id插入到表中
            ManualCustomer mcs = new ManualCustomer();
            mcs.setScrId(srcId);
            mcs.setDstId(dstId);
            mcs.setMsg(message);
            // Date date = new Date();
            // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd
            // HH:mm:ss");
            // String dataNow = sdf.format(date);
            String dataNow = DateUtil.getFormatDate("yyyy-MM-dd HH:mm:ss");
            mcs.setSendTime(dataNow);
            mcs.setPull("0");
            manualcustomerDao.insertManualCustomer(mcs);
            // 日志
            logger.info("userSendMsg mcs信息:{}", mcs);
            customerContext = CustomerContext.getInstance();
            if (!customerContext.userSendMsg(srcId, dstId, mcs.getId(), message, dataNow)) {
                maxmap.put("result", "1");
                maxmap.put("ErrMsg", "发送失败");
                logger.error("{} user send to {} fail....", srcId, dstId);
                return JSON.toJSONString(maxmap, true);
            }
            // 查询表的属性
            ArrayList<CommunionMsg> arraylist = customerContext.userPullMsg(srcId);
            // Arraymsg数组中的
            if (arraylist != null) {
                for (CommunionMsg one : arraylist) {
                    Map<String, Object> map = new HashMap<String, Object>();
                    map.put("msgid", one.getMsgid());
                    map.put("from_id", one.getScrId());
                    map.put("to_id", srcId);
                    map.put("message", one.getMsg());
                    map.put("msgTime", one.getSendTime());
                    list.add(map);
                }
                // 发送成功，返回状态0,条数和Arraymsg数组
            }
            maxmap.put("msg_count", arraylist == null ? 0 : arraylist.size());
            maxmap.put("Arraymsg", list);
            maxmap.put("result", "0");
            // 日志
            logger.info("userSendMsg maxmap:{}", maxmap);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("userSendMsg error:", e);
            // 发送给失败，返回 状态 1，失败原因
            maxmap.put("result", "1");
            maxmap.put("msg", "发送失败");
        }

        // 转成JsontoString
        String json = JSON.toJSONString(maxmap, true);
        // JSONObject jsonmaxmap = JSONObject.parseObject(maxmap.toString());
        // 日志
        logger.info("userSendMsg out json:{}", json);
        return json;
    }

    /**
     * 客服发送 消息
     */

    public String serverSendMsg(int srcId, int dstId, String message) {
        // 日志
        logger.info("serverSendMsg in:{},{},{}", srcId, dstId, message);
        // 查询表的属性
        Map<String, Object> maxmap = new HashMap<String, Object>();
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        try {
            // 先发送者会发送消息给接受者通过接受者的 id插入到表中
            ManualCustomer mcs = new ManualCustomer();
            mcs.setScrId(srcId);
            mcs.setDstId(dstId);
            mcs.setMsg(message);
            // Date date = new Date();
            // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd
            // HH:mm:ss");
            // String dataNow = sdf.format(date);
            String dataNow = DateUtil.getFormatDate("yyyy-MM-dd HH:mm:ss");
            mcs.setSendTime(dataNow);
            mcs.setPull("0");
            manualcustomerDao.insertManualCustomer(mcs);
            // 日志
            logger.info("serverSendMsg mcs信息:{}", mcs);
            customerContext = CustomerContext.getInstance();
            if (!customerContext.serverSendMsg(srcId, dstId, mcs.getId(), message, dataNow)) {
                maxmap.put("result", "1");
                maxmap.put("ErrMsg", "发送失败");
                logger.error("{} server send to {} fail....", srcId, dstId);
                return JSON.toJSONString(maxmap, true);
            }
            customerContext = CustomerContext.getInstance();
            ArrayList<CommunionMsg> clientsMsg = customerContext.serverPullMsg(srcId, dstId);
            for (CommunionMsg one : clientsMsg) {
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("msgId", one.getMsgid());
                map.put("message", one.getMsg());
                map.put("msgTime", one.getSendTime());
                list.add(map);
            }

        } catch (Exception e) {
            e.printStackTrace();
            logger.error("serverSendMsg error:", e);
            // 发送给失败，返回 状态 1，失败原因
            maxmap.put("result", "1");
            maxmap.put("ErrMsg", "发送失败");
        }
        // 发送成功，返回状态0,条数和Arraymsg数组
        maxmap.put("result", "0");
        maxmap.put("msgArray", list);

        // 转成JsontoString
        String json = JSON.toJSONString(maxmap, true);
        // 日志
        logger.info("serverSendMsg out json:{}", json);
        return json;
    }

    // 用户接受消息

    public String clientGetMsg(int userId) {
        // user_id可能 是用户id，也可能是客服 id
        // 日志
        logger.info("clientGetMsg in:{}", userId);
        Map<String, Object> maxmap = new HashMap<String, Object>();
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        try {
            // 先，接受者接受发送者发送的消息，通过接受者的id
            customerContext = CustomerContext.getInstance();
            ArrayList<CommunionMsg> arraylist = customerContext.userPullMsg(userId);

            if (arraylist != null) {
                // Arraymsg数组中的
                for (CommunionMsg one : arraylist) {
                    Map<String, Object> map = new HashMap<String, Object>();
                    map.put("msgid", one.getMsgid());
                    map.put("from_id", one.getScrId());
                    map.put("to_id", userId);
                    map.put("message", one.getMsg());
                    map.put("msgTime", one.getSendTime());
                    list.add(map);
                }
            }

            // 接受成功后返回状态0，条数和Arraylist数组
            maxmap.put("result", "0");
            maxmap.put("msg_count", arraylist == null ? 0 : arraylist.size());
            maxmap.put("Arraymsg", list);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("clientGetMsg error:", e);
            // 接受失败返回状态 1，失败原因
            maxmap.put("result", "1");
            maxmap.put("ErrMsg", "接受失败 ");
        }
        // 转成JsontoString
        String json = JSON.toJSONString(maxmap, true);

        // 日志
        logger.info("clientGetMsg out json:{}", json);
        return json;
    }

    /**
     * 客服接受消息
     */

    public String serverGetMsg(int serverId, int userId) {
        // user_id可能 是用户id，也可能是客服 id
        // 日志
        logger.info("serverGetMsg in:{}--{}", serverId, userId);
        Map<String, Object> maxmap = new HashMap<String, Object>();
        try {
            List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
            customerContext = CustomerContext.getInstance();
            if (0 != userId) {
                ArrayList<CommunionMsg> clientsMsg = customerContext.serverPullMsg(serverId, userId);
                for (CommunionMsg one : clientsMsg) {
                    Map<String, Object> map = new HashMap<String, Object>();
                    map.put("msgId", one.getMsgid());
                    map.put("message", one.getMsg());
                    map.put("msgTime", one.getSendTime());
                    list.add(map);
                }
            } else { // 自动分配客户消息
                ArrayList<CommunionMsg> serverSystemMsg = customerContext.getServerSystemMsg(serverId);
                if (serverSystemMsg != null) {
                    for (CommunionMsg one : serverSystemMsg) {
                        Map<String, Object> map = new HashMap<String, Object>();
                        User userinfo = userdao.selectId(one.getScrId());
                        map.put("msgId", one.getMsgid());
                        map.put("message", one.getMsg());
                        map.put("clientId", one.getScrId());
                        map.put("msgTime", one.getSendTime());
                        map.put("userName", userinfo.getUserName());
                        map.put("headPic", userinfo.getHeadPic());
                        list.add(map);
                    }
                }
            }

            // 接受成功后返回状态0，条数和Arraylist数组
            maxmap.put("result", "0");
            maxmap.put("msgArray", list);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("serverGetMsg error:", e);
            // 接受失败返回状态 1，失败原因
            maxmap.put("result", "1");
            maxmap.put("ErrMsg", "接受失败 ");
        }
        // 转成JsontoString
        String json = JSON.toJSONString(maxmap, true);

        // 日志
        logger.info("serverGetMsg out json:{}", json);
        return json;
    }

    /**
     * 客服拉取最近30分钟消息
     */

    public String serverGetLastMsg(int serverId) {
        // 日志
        logger.info("serverGetLastMsg in:{}", serverId);

        Map<String, Object> maxmap = new HashMap<String, Object>();
        try {
            List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
            // 获取
            customerContext = CustomerContext.getInstance();
            for (Entry<Integer, ArrayList<CommunionMsg>> clientMsgMap : customerContext.getServersMap().get(serverId)
                    .getMessageList().entrySet()) {

                int clientId = clientMsgMap.getKey();
                User user = userdao.selectId(clientId);
                ArrayList<CommunionMsg> msgs = clientMsgMap.getValue();

                // Arraymsg数组中的
                List<Map<String, Object>> list1 = new ArrayList<Map<String, Object>>();
                for (CommunionMsg msg : msgs) {
                    Map<String, Object> map1 = new HashMap<String, Object>();
                    map1.put("msgId", msg.getMsgid());
                    map1.put("srcId", msg.getScrId());
                    map1.put("dstId", msg.getDstId());
                    map1.put("msgTime", msg.getSendTime());
                    map1.put("msg", msg.getMsg());
                    list1.add(map1);
                }
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("clientId", clientId);
                map.put("clientName", user.getUserName());
                map.put("headPic", user.getHeadPic());
                map.put("msgArray", list1);
                list.add(map);
            }
            maxmap.put("clientArray", list);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("serverGetLastMsg error:", e);
            // 接受失败返回状态 1，失败原因
            maxmap.put("result", "1");
            maxmap.put("ErrMsg", "获取失败 ");
        }
        maxmap.put("result", "0");

        // 转成JsontoString
        String json = JSON.toJSONString(maxmap, true);
        // 日志
        logger.info("serverGetLastMsg out json:{}", json);
        return json;
    }

    /**
     * 客服拉取历史消息
     */

    public String serverGetHistoryMsg(int serverId, int userId, int pageNum, int pageSize, int minMsgId) {
        // 日志
        logger.info("serverGetHistoryMsg in:serverId{},userId{},pageNum{},pageSize{},minMsgId{}", serverId, userId,
                pageNum, pageSize, minMsgId);
        Map<String, Object> maxmap = new HashMap<String, Object>();
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();

        try {

            int skip = (pageNum - 1) * pageSize;
            Map<String, Integer> params = new HashMap<String, Integer>();
            params.put("serverId", serverId);
            params.put("skip", skip);
            params.put("pageSize", pageSize);
            // params.put("minMsgId", minMsgId);
            // 先客服 会根据自身的id和客户的id进行对数据库中查询，有则拉取回来
            ArrayList<ManualCustomer> msgs;
            if (userId != 0) {
                params.put("userId", userId);
                msgs = manualcustomerDao.SelectServerMsg(params);
            } else {
                msgs = manualcustomerDao.SelectServerMsg1(params);
            }

            // 日志
            logger.info("selectByDstId信息:{}", msgs);
            // 接着判断pageNum=0时

            for (ManualCustomer one : msgs) {
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("msgId", one.getId());
                map.put("srcId", one.getScrId());
                map.put("dstId", one.getDstId());
                map.put("msgTime", one.getSendTime());
                map.put("msg", one.getMsg());

                list.add(map);
            }
            // 接受成功后返回状态0,Arraylist数组
            maxmap.put("result", "0");
            maxmap.put("clientArray", list);

        } catch (Exception e) {
            e.printStackTrace();
            logger.error("serverGetHistoryMsg error:", e);
            maxmap.put("result", "1");
            maxmap.put("Errmsg", "失败");
        }
        // 转成JsontoString
        String json = JSON.toJSONString(maxmap, true);
        // 日志
        logger.info("serverGetHistoryMsg out json:{}", json);
        return json;
    }

    /**
     * 客户端拉取历史消息
     */

    public String clientGetHistoryMsg(int userId, int pageNum, int pageSize) {
        // 日志
        logger.info("clientGetHistoryMsg in:userId{},pageNum{},pageSize{}", userId, pageNum, pageSize);
        Map<String, Object> maxmap = new HashMap<String, Object>();
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();

        try {
            int skip = (pageNum - 1) * pageSize;
            Map<String, Integer> params = new HashMap<String, Integer>();
            params.put("userId", userId);
            params.put("skip", skip);
            params.put("pageSize", pageSize);
            // 先客服 会根据自身的id和客户的id进行对数据库中查询，有则拉取回来
            ArrayList<ManualCustomer> msgs = manualcustomerDao.SelectClientMsg(params);

            // 日志
            logger.info("selectByDstId信息:{}", msgs);
            // 接着判断pageNum=0时

            for (ManualCustomer one : msgs) {
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("msgId", one.getId());
                map.put("srcId", one.getScrId());
                map.put("dstId", one.getDstId());
                map.put("msgTime", one.getSendTime());
                map.put("msg", one.getMsg());
                list.add(map);
            }
            // 接受成功后返回状态0,Arraylist数组
            maxmap.put("result", "0");
            maxmap.put("clientArray", list);

        } catch (Exception e) {
            e.printStackTrace();
            logger.error("clientGetHistoryMsg error:", e);
            maxmap.put("result", "1");
            maxmap.put("Errmsg", "失败");
        }
        // 转成JsontoString
        String json = JSON.toJSONString(maxmap, true);
        // 日志
        logger.info("clientGetHistoryMsg out json:{}", json);
        return json;
    }

    /**
     * 客服端拉取历史消息
     */

    public String serverGetClientId(int serverId, int userId) {
        JSONObject jObject = new JSONObject();
        try {
            // 获取
            customerContext = CustomerContext.getInstance();
            // 客服获取客服ID
            int ret = customerContext.getClentId(serverId, userId);
            if (0 == ret) {
                jObject.put("result", "1");
                jObject.put("msg", "当前客户已经被分配，请拉取其他客户");
                return jObject.toJSONString();
            } else if (-1 == ret) {
                jObject.put("result", "2");
                jObject.put("msg", "您已经达到最大客服同时在线数，请先关闭已经服务完成的客户");
                return jObject.toJSONString();
            }

            jObject.put("result", "0");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("serverGetClientId error:", e);
            jObject.put("result", "3");
            jObject.put("msg", "获取失败 ");
        }

        return jObject.toJSONString();

    }

    /**
     * 客服登录
     */

    public String serverLogin(String userMark, String password, String deviceId) {
        JSONObject jObject = new JSONObject();

        try {
            // 判断账号是否为空
            if (userMark == null || userMark.trim().isEmpty()) {
                jObject.put("result", "1");
                jObject.put("msg", "帐户名不能为空");
                return jObject.toJSONString();
            }
            // 判断账号的长度
            if (userMark.length() > 14 || userMark.length() < 1) {
                jObject.put("result", "2");
                jObject.put("msg", "帐户名长度不对");
                return jObject.toJSONString();
            }
            // 判断密码
            if (password == null || password.trim().isEmpty()) {
                jObject.put("result", "4");
                jObject.put("msg", "密码不能为空");
                return jObject.toJSONString();
            }

            // 查询表中是否有这个账户
            CustomerServiceInformation selectByName = customerdao.selectByName(userMark);
            // 判断用户是否存在
            if (selectByName == null) {
                jObject.put("result", "3");
                jObject.put("msg", "用户不存在");
                return jObject.toJSONString();
            }

            // 判断客服是否被冻结
            if (selectByName.getState().equals("1")) {
                jObject.put("result", "3");
                jObject.put("msg", "用户已冻结");
                return jObject.toJSONString();
            }

            // 判断表 中密码和输入密码是否一致
            if (password.equals(selectByName.getPassword())) {
                // 登录成功
                // 返回用户信息
                // 生成一个token
                String tmpStr = userMark + "," + System.currentTimeMillis();
                String token = UtilsDto.crypt(tmpStr);

                // 把token存入jedisClient
                jedisClient.set(String.valueOf("customertoken" + selectByName.getId()), token);

                // 客服登录 建立客服服务记录
                CustomerContext customerContext = CustomerContext.getInstance();
                logger.debug("customer on hashcode:{}", customerContext.hashCode());
                customerContext.serverOnline(selectByName.getId(), selectByName.getMaximum());


                // 记录单点登陆信息
                InitData.ONLINE_MAP.get("88888").put(selectByName.getId(), (System.currentTimeMillis() / 1000));
                InitData.SSO_MAP.put(selectByName.getId(), deviceId);

                jObject.put("result", "0");
                jObject.put("userId", selectByName.getId());
                jObject.put("headPic", selectByName.getHeadPic());
                jObject.put("userName", selectByName.getServerName());
                jObject.put("nickName", selectByName.getNickName());
                jObject.put("token", token);
                jObject.put("msg", "登录成功");

            } else {
                jObject.put("result", "5");
                jObject.put("msg", "密码错误");
            }

        } catch (Exception e) {
            e.printStackTrace();
            logger.error("serverLogin error:", e);
            jObject.put("result", "6");
            jObject.put("msg", "登录失败");
        }
        return jObject.toJSONString();
    }

    /**
     * 修改密码接口
     */

    public String serverModifyPasswd(Integer userId, String newPassword, String oldPassword) {
        JSONObject jObject = new JSONObject();
        try {
            // 根据userId查询出他的信息
            CustomerServiceInformation customer = customerdao.selectById(userId);
            // 判断有没有这个用户
            if (customer == null) {
                jObject.put("result", "2");
                jObject.put("msg", "没有这个用户");
                return jObject.toJSONString();
            }
            // 判断表中的密码和客服输入的旧密码是否一样
            if (!customer.getPassword().equals(oldPassword)) {
                logger.error("modify fail {}--{}", customer.getPassword(), oldPassword);
                jObject.put("result", "1");
                jObject.put("msg", "输入的原密码错误");
                return jObject.toJSONString();
            }
            CustomerServiceInformation ct = new CustomerServiceInformation();
            ct.setId(userId);
            ct.setPassword(newPassword);
            customerdao.updateByServer(ct);
            jObject.put("result", "0");
            jObject.put("msg", "修改密码成功");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("serverModifyPasswd error:", e);
            jObject.put("result", "6");
            jObject.put("msg", "修改密码失败");
        }
        return jObject.toJSONString();
    }

    /**
     * 客服修改个人信息
     */

    public String updatecustomerInfo(int serverId, String nickName, String phoneNum) {
        JSONObject jObject = new JSONObject();
        try {

            // 判断昵称最高不超过14个长度[a-zA-Z]{1,14}|[\u4e00-\u9fa5]{1,7}
            String str = "/^[\u4e00-\u9fa5a-zA-Z0-9_]+$/";
            if (nickName.matches(str)) {
                jObject.put("result", "2");
                jObject.put("msg", "请输入1~14个英文字母或者不超过7个中文汉字 ");
                return jObject.toJSONString();
            }

            // 判断手机号1开头，不能低于11位数
            if (phoneNum.startsWith("1") && phoneNum.length() == 11) {
                try {
                    // 字符串转换成Long型的数字
                    Long i = Long.parseLong(phoneNum);
                    logger.info("phoneNum:{}", i);
                } catch (Exception e) {
                    e.printStackTrace();
                    jObject.put("result", "3");
                    jObject.put("msg", "手机号不正确");
                    return jObject.toJSONString();
                }
            } else {
                jObject.put("result", "4");
                jObject.put("msg", "手机号不正确");
                return jObject.toJSONString();
            }
            // 根据id查询出 这个客服
            CustomerServiceInformation selectById = customerdao.selectById(serverId);

            if (selectById == null) {
                jObject.put("result", "1");
                jObject.put("msg", "没有这个客服");
                return jObject.toJSONString();
            }

            // 修改信息后存入 表中
            CustomerServiceInformation csf = new CustomerServiceInformation();
            csf.setId(serverId);
            csf.setNickName(nickName);
            csf.setPhoneNum(phoneNum);
            customerdao.updataServer(csf);

            // 返回状态
            jObject.put("result", "0");
            jObject.put("msg", "修改成功");

        } catch (Exception e) {
            e.printStackTrace();
            logger.error("updatecustomerInfo error:", e);
            // 返回状态
            jObject.put("result", "5");
            jObject.put("msg", "修改失败");

        }
        return jObject.toJSONString();
    }

    /**
     * 客服充值接口
     */

    @Transactional(rollbackFor = Exception.class)
    public String customerRecharge(int serverId, String token, int userId, int rechargeAmount, int rechargeDiamond,
                                   String orderId) throws Exception {
        JSONObject jObject = new JSONObject();
        Account account = new Account();
        try {
            // 客服验证
            String rToken = jedisClient.get(String.valueOf("customertoken" + serverId));
            if (!token.equals(rToken)) {
                jObject.put("result", "2");
                jObject.put("msg", "客服身份验证失败");
                return jObject.toJSONString();
            }

            AccountTransaction selectByorderId = accounttransactiondao.selectByorderId(orderId);
            if (selectByorderId != null) {
                jObject.put("result", "2");
                jObject.put("msg", "订单号已经充值！");
                return jObject.toJSONString();
            }

            // 先根据用户 id来查询出 account表中有没有这个用户
            Account userAccount = accountdao.selectAccountByUserId(userId);
            if (userAccount == null) {
                jObject.put("result", "3");
                jObject.put("msg", "没有这个客户");
                return jObject.toJSONString();
            }
            // 再根据userid对 account表进行插入彩钻数量
            // 先加上原先 的彩钻数量
            account.setUserId(userId);
            account.setAccountFunds(rechargeDiamond);
            int updateNum = accountdao.addAccount(account);
            logger.info("********updateNum*****{}", updateNum);
            if (updateNum == 0) {
                jObject.put("result", "4");
                jObject.put("msg", "充值异常");
                return jObject.toJSONString();
            }

            // 获取这个用户 的账号id
            int accountId = userAccount.getId();
            // 向这个表中插入充值金额 ，账户变动时间，账户变更类型 ，资金 来源 ，备注
            AccountTransaction accounttransaction = new AccountTransaction();
            accounttransaction.setOrderId(RandCodeUtil.getOrderId());
            accounttransaction.setAccountId(accountId);
            accounttransaction.setTransactionDate(new Date());
            accounttransaction.setTransactionMoney(rechargeDiamond);
            accounttransaction.setOrderId(orderId);
            accounttransaction.setMoney(rechargeAmount);
            accounttransaction.setTransactionType(1);
            accounttransaction.setMoneySources("客服充值");
            accounttransaction.setState(1);
            accounttransaction.setRemarks("充值客服：" + String.valueOf(serverId));
            accounttransaction.setOperator(serverId);
            accounttransaction.setFinishTime(DateUtil.getFormatDate("yyyy-MM-dd HH:mm:ss"));
            accounttransactiondao.insertAccountTransaction(accounttransaction);

            Notice notice = new Notice();
            notice.setNoticeDate(new Date());
            notice.setUserId(userId); // 管理员发布公告默认 user_id=0
            notice.setNoticeInfo("您好，您充值的" + rechargeAmount + "元已经到账！");
            notice.setBeread(0);
            noticeDao.insertNotice(notice);

            // 分成计算
            User user = userdao.selectId(userId);
            String agencyId = user.getAgencyId();
            if (agencyId != null && !agencyId.equals("")) {
                Agency agency = agencydao.selectAgency(agencyId);
                if (agency != null) {
                    BettingLimitation betLimit = bettinglimitationDao.selectMaxMinBet();
                    double rebateAmount = rechargeAmount * betLimit.getChannel();

                    account.setUserId(agency.getUserId());
                    account.setAccountFunds(rebateAmount);
                    updateNum = accountdao.addAccount(account);
                    logger.info("********updateNum*****{}", updateNum);
                    if (updateNum > 0) {
                        Account account1 = accountdao.selectAccountByUserId(agency.getUserId());
                        AccountTransaction at = new AccountTransaction();
                        at.setAccountId(account1.getId());
                        at.setTransactionDate(new Date());
                        at.setTransactionMoney(rebateAmount);
                        at.setOrderId(RandCodeUtil.getOrderId());
                        at.setMoney(rebateAmount);
                        at.setTransactionType(9);
                        at.setMoneySources("充值分成");
                        at.setState(1);
                        at.setRemarks("充值分成：" + String.valueOf(serverId));
                        at.setFinishTime(DateUtil.getFormatDate("yyyy-MM-dd HH:mm:ss"));
                        accounttransactiondao.insertAccountTransaction(at);
                    }
                }
            }

            jObject.put("result", "0");
            jObject.put("msg", "充值成功");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("customerRecharge error:", e);
            jObject.put("result", "1");
            jObject.put("msg", "充值失败");
            throw new Exception("充值失败");
        }
        return jObject.toJSONString();
    }

    /**
     * 获取彩钻数量接口
     */

    public String getDiamondNum(int serverId, int rechargeAmount, int flag) {
        JSONObject jObject = new JSONObject();
        try {
            if (rechargeAmount > Integer.parseInt(LIMITAUTOCASH)) {
                jObject.put("result", "1");
                jObject.put("msg", "单次额度最大为" + LIMITAUTOCASH);
                return jObject.toJSONString();
            }
            jObject.put("result", "0");
            jObject.put("msg", "获取成功");
            jObject.put("rechargeDiamond", rechargeAmount);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("getDiamondNum error:", e);
            jObject.put("result", "1");
            jObject.put("msg", "获取失败");
        }
        return jObject.toJSONString();
    }


    @Transactional(rollbackFor = Exception.class)
    public String customerCash(int serverId, String token, int userId, int withdrawcash, int withdrawDiamond)
            throws Exception {

        JSONObject jObject = new JSONObject();
        Account account = new Account();
        try {
            // 客服验证
            String rToken = jedisClient.get(String.valueOf("customertoken" + serverId));
            if (!token.equals(rToken)) {
                jObject.put("result", "2");
                jObject.put("msg", "客服身份验证失败");
                return jObject.toJSONString();
            }
            // 先根据用户 id来查询出 account表中有没有这个用户
            Account userAccount = accountdao.selectAccountByUserId(userId);
            if (userAccount == null) {
                jObject.put("result", "3");
                jObject.put("msg", "没有这个客户");
                return jObject.toJSONString();
            }

            if (userAccount.getAccountFunds() < withdrawDiamond) {
                jObject.put("result", "4");
                jObject.put("msg", "余额不足");
                return jObject.toJSONString();
            }
            account.setUserId(userId);
            account.setAccountFunds(withdrawDiamond);
            int updateNum = accountdao.reduceAccount(account);
            logger.info("********updateNum*****{}", updateNum);
            if (updateNum == 0) {
                jObject.put("result", "5");
                jObject.put("msg", "提现异常");
                return jObject.toJSONString();
            }

            // 获取这个用户 的账号id
            int accountId = userAccount.getId();
            // 向这个表中插入充值金额 ，账户变动时间，账户变更类型 ，资金 来源 ，备注
            AccountTransaction accounttransaction = new AccountTransaction();
            accounttransaction.setOrderId(RandCodeUtil.getOrderId());
            accounttransaction.setAccountId(accountId);
            accounttransaction.setTransactionDate(new Date());
            accounttransaction.setTransactionMoney(withdrawDiamond);
            accounttransaction.setMoney(withdrawcash);
            accounttransaction.setTransactionType(2);
            accounttransaction.setMoneyGo("客服提现");
            accounttransaction.setRemarks("客服提现ID：" + String.valueOf(serverId));
            accounttransaction.setOperator(serverId);
            accounttransaction.setState(1);
            accounttransaction.setFinishTime(DateUtil.getFormatDate("yyyy-MM-dd HH:mm:ss"));
            accounttransactiondao.insertAccountTransaction(accounttransaction);
            jObject.put("result", "0");
            jObject.put("msg", "提现成功");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("customerCash error:", e);
            jObject.put("result", "1");
            jObject.put("msg", "提现失败");
            throw new Exception("提现失败");
        }
        return jObject.toJSONString();
    }


    @Transactional(rollbackFor = Exception.class)
    public String autoCash(int userId, int cashType, int withdrawDiamond, String cashAccout, String cashName,
                           int amount, String phoneNum, String code) throws Exception {
        // 先根据用户 id来查询出 account表中有没有这个用户
        JSONObject jObject = new JSONObject();
        try {

            if (amount > Integer.parseInt(LIMITAUTOCASH) || amount < 10) {
                jObject.put("result", "7");
                jObject.put("msg", "单次限额为10--" + LIMITAUTOCASH);
                return jObject.toJSONString();
            }

            String rCode = jedisClient.get(LOGINSYSTEM1 + phoneNum);
            if (!code.equals(rCode)) {
                jObject.put("result", "5");
                jObject.put("msg", "短信验证码错误");
                return jObject.toJSONString();
            }
            jedisClient.del(LOGINSYSTEM1 + phoneNum);

            if (1 == cashType && cashName.equals("")) {
                jObject.put("result", "2");
                jObject.put("msg", "银行卡转账，持卡人不能为空");
                return jObject.toJSONString();
            }

            Account userAccount = accountdao.selectAccountByUserId(userId);
            if (userAccount == null) {
                jObject.put("result", "2");
                jObject.put("msg", "没有这个客户");
                return jObject.toJSONString();
            }

            User user = userdao.selectId(userId);
            if (user.getState().equals("2")) {
                jObject.put("result", "2");
                jObject.put("msg", "不允许提现");
                return jObject.toJSONString();
            } else if (user.getState().equals("0")) {
                jObject.put("result", "2");
                jObject.put("msg", "此用户已被冻结");
                return jObject.toJSONString();
            }

            // 首次提现判断
            int cnt = accounttransactiondao.selectTransactionCountById(userAccount.getId());
            if (cnt == 0) {
                if (userAccount.getAccountFunds() < 288) {
                    jObject.put("result", "3");
                    jObject.put("msg", "首次提现余额要大于288");
                    return jObject.toJSONString();
                }
                if (userAccount.getAccountFunds() - amount < 28) {
                    jObject.put("result", "3");
                    jObject.put("msg", "首次提现后余额要大于28");
                    return jObject.toJSONString();
                }
                int sumAmunt = bettinginfoDao.selectUserbetAmount(userId);
                if (sumAmunt < 288) {
                    jObject.put("result", "3");
                    jObject.put("msg", "首次提现时下注总额要超过288");
                    return jObject.toJSONString();
                }
            }

            if (userAccount.getAccountFunds() < withdrawDiamond) {
                jObject.put("result", "3");
                jObject.put("msg", "余额不足");
                return jObject.toJSONString();
            }

            if (accounttransactiondao.getCashTimes(userAccount.getId()) > Integer.parseInt(AUTOCASH)) {
                jObject.put("result", "6");
                jObject.put("msg", "超出提现次数");
                return jObject.toJSONString();
            }

            Account account = new Account();
            account.setUserId(userId);
            account.setAccountFunds(withdrawDiamond);
            int updateNum = accountdao.reduceAccount(account);
            logger.info("********updateNum*****{}", updateNum);
            if (updateNum == 0) {
                jObject.put("result", "4");
                jObject.put("msg", "提现异常");
                return jObject.toJSONString();
            }

            // 获取这个用户 的账号id
            int accountId = userAccount.getId();
            // 向这个表中插入充值金额 ，账户变动时间，账户变更类型 ，资金 来源 ，备注
            double commission = 0.0;
            if (amount > 100) {
                commission = amount * 0.02;
            } else {
                commission = 3;
            }
            AccountTransaction accounttransaction = new AccountTransaction();
            accounttransaction.setOrderId(RandCodeUtil.getOrderId());
            accounttransaction.setAccountId(accountId);
            accounttransaction.setTransactionDate(new Date());
            accounttransaction.setTransactionMoney(withdrawDiamond);
            accounttransaction.setMoney(amount);
            accounttransaction.setFee(commission);
            accounttransaction.setTransactionType(6);
            accounttransaction.setCashType(cashType);
            accounttransaction.setCashAccout(cashAccout);
            accounttransaction.setCashName(cashName);
            if (amount > 3000) {
                accounttransaction.setState(4);
            } else {
                accounttransaction.setState(0);
            }
            accounttransaction.setMoneyGo("自动提现");
            accounttransaction.setRemarks("自主提现");
            accounttransactiondao.insertAccountTransaction(accounttransaction);
            jObject.put("result", "0");
            jObject.put("msg", "提现成功");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("autoCash error:", e);
            jObject.put("result", "1");
            jObject.put("msg", "提现失败,未知原因，请联系客服");
            throw new Exception("autoCash error");
        }
        return jObject.toJSONString();
    }

    /**
     * 修改订单状态
     */

    @Transactional(rollbackFor = Exception.class)
    public String updateState(String orderId, int state, String remark) throws Exception {
        JSONObject jObject = new JSONObject();
        try {
            // if (null != HOSTADDR && !"".equals(HOSTADDR)) {
            //
            // if (!hostAddr.equals(HOSTADDR)) {
            // jObject.put("result", "2");
            // jObject.put("msg", "访问地址有误");
            // return jObject.toJSONString();
            // }
            // }
            AccountTransaction selectByorderId = accounttransactiondao.selectByorderId(orderId);
            if (selectByorderId == null) {
                jObject.put("result", "2");
                jObject.put("msg", "没有这个订单号！");
                return jObject.toJSONString();
            }
            if (selectByorderId.getState() == 1 || selectByorderId.getState() == 2) {
                jObject.put("result", "2");
                jObject.put("msg", "此订单已经更新为成功或者失败状态，不允许更改！");
                return jObject.toJSONString();
            }

            // 失败返还客户金额
            if (state == 2) {
                Account account = new Account();
                account.setId(selectByorderId.getAccountId());
                account.setAccountFunds(selectByorderId.getTransactionMoney());

                int updateNum = accountdao.addAccountById(account);
                logger.info("********updateNum*****{}", updateNum);
                if (updateNum == 0) {
                    jObject.put("result", "3");
                    jObject.put("msg", "系统异常");
                    return jObject.toJSONString();
                }
            }

            AccountTransaction ac = new AccountTransaction();
            ac.setState(state);
            ac.setId(selectByorderId.getId());
            ac.setRemarks(remark);
            // ac.setRealtransfermoney(aliRealTransfer);
            // ac.setAliFee(aliFee);
            // ac.setAotoTransferId(aotoTransferId);
            accounttransactiondao.updateAccountTransaction(ac);
            jObject.put("result", "0");
            jObject.put("msg", "修改成功");

        } catch (Exception e) {
            e.printStackTrace();
            logger.error("updateState error:", e);
            jObject.put("result", "1");
            jObject.put("msg", "修改失败");
            throw new Exception("regist error");
        }
        return jObject.toJSONString();
    }


    public String getUnknowOrders(String hostAddr) {
        Map<String, Object> maxmap = new HashMap<String, Object>();
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        try {
            // if (null != HOSTADDR && !"".equals(HOSTADDR)) {
            //
            // if (!hostAddr.equals(HOSTADDR)) {
            // // maxmap.put("result", "2");
            // // maxmap.put("msg", "访问地址有误");
            // return JSON.toJSONString(list, true);
            // }
            // }

            List<AccountTransaction> tranList = accounttransactiondao.selectAccountTransactionBystate(3);
            for (AccountTransaction one : tranList) {
                AccountTransaction selectByorderId = accounttransactiondao.selectByorderId(one.getOrderId());
                Account ac = accountdao.selectAccountById(selectByorderId.getAccountId());
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("orderId", one.getOrderId());
                map.put("cashMoney", "" + (int) one.getTransactionMoney());
                map.put("userId", ac.getUserId());
                map.put("cashAccount", one.getCashAccout());
                map.put("cashName", one.getCashName());
                // map.put("alipay_account", one.getCashAccout());
                map.put("type", one.getCashType());

                // String userRealGetMoney = "";
                // if (one.getMoney() > 100.0) {
                // userRealGetMoney = "" + (int) (one.getMoney() * (1 - 0.02));
                // } else {
                // userRealGetMoney = "" + ((int) (one.getMoney()) - 3);
                // }
                // map.put("user_real_get_money", userRealGetMoney);
                // map.put("alipay_real_name", one.getCashName());
                list.add(map);
            }
            maxmap.put("array", list);
            maxmap.put("result", "0");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("getUnknowOrders error:", e);
            maxmap.put("result", "1");
            maxmap.put("msg", "获取失败");
            return JSON.toJSONString(maxmap, true);
        }
        return JSON.toJSONString(maxmap, true);
    }


    public String getOrders(String hostAddr) {
        Map<String, Object> maxmap = new HashMap<String, Object>();
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        try {
            // if (null != HOSTADDR && !"".equals(HOSTADDR)) {
            //
            // if (!hostAddr.equals(HOSTADDR)) {
            // // maxmap.put("result", "2");
            // // maxmap.put("msg", "访问地址有误");
            // return JSON.toJSONString(list, true);
            // }
            // }

            List<AccountTransaction> tranList = accounttransactiondao.selectAccountTransactionBystate(0);
            for (AccountTransaction one : tranList) {
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("id", one.getOrderId());
                map.put("cash_money", "" + (int) one.getMoney());
                map.put("alipay_account", one.getCashAccout());
                // map.put("type", one.getCashType());

                String userRealGetMoney = "";
                if (one.getMoney() > 100.0) {
                    userRealGetMoney = "" + (int) (one.getMoney() * (1 - 0.02));
                } else {
                    userRealGetMoney = "" + ((int) (one.getMoney()) - 3);
                }
                map.put("user_real_get_money", userRealGetMoney);
                map.put("alipay_real_name", one.getCashName());
                list.add(map);
            }
            // maxmap.put("array", list);
            // maxmap.put("result", "0");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("getOrders error:", e);
            // maxmap.put("result", "1");
            // maxmap.put("msg", "获取失败");
            // return JSON.toJSONString(list, true);
        }
        return JSON.toJSONString(list, true);
    }


    public String clientgetcash(int userId, int withdrawDiamond) {
        JSONObject jObject = new JSONObject();
        try {
            if (withdrawDiamond > 1000000) {
                jObject.put("result", "1");
                jObject.put("msg", "单次最大额度为1000000");
                return jObject.toJSONString();
            }
            jObject.put("result", "0");
            jObject.put("msg", "获取成功");
            jObject.put("withdrawDiamond", withdrawDiamond);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("clientgetcash error:", e);
            jObject.put("result", "2");
            jObject.put("msg", "获取失败");
        }
        return jObject.toJSONString();
    }

    /**
     * 返点操作
     */

    @Transactional(rollbackFor = Exception.class)
    public void RebateService() throws Exception {
        logger.debug("go to RebateService......");
        String key = DateUtil.getFormatDate("yyyyMMdd");
        if (jedisClient.incr(key) != 1) {
            logger.debug("go to RebateService again, will return......");
            return;
        }
        jedisClient.expire(key, 10 * 60);
        List<Agency> agencies = agencydao.selectAllAgency();
        List<Agency> proxys = agencydao.selectAllProxy();
        Map<String,Agency> userAgencyMap = new HashMap<>();
        Map<String,Agency> userAgencyMapForUp = new HashMap<>();
        Map<String,Agency> proxyAgencyMap = new HashMap<>();
        //用户反水(所有的agency)
        agencies.forEach((k)->{
            userAgencyMap.put(k.getId(),k);
            if(k.getCommitSwitch() == 1){
                userAgencyMapForUp.put(k.getId(),k);
            }
        });
        List<String> list = new ArrayList<>();
        proxys.forEach((k)->{
            Agency ag = userAgencyMap.get(k.getProxyRefAgency()+"");
            userAgencyMap.put(k.getId(),ag);
            if(userAgencyMapForUp.get(k.getProxyRefAgency()+"")!=null){
                Agency agency = userAgencyMapForUp.get(k.getProxyRefAgency()+"");
                list.add(k.getId());
                proxyAgencyMap.put(k.getId(),agency);
            }
        });


        int pageNow = 1;
        try {
            while (true) {
                int startCount = (pageNow - 1) * 50;
                List<Rebate> queryRebate = accounttransactionDao.queryRebate(startCount);
                if (null == queryRebate || queryRebate.size() == 0) {
                    break;
                }
                for (Rebate rebate : queryRebate) {
                    logger.debug("rebate: {} -- {}", rebate.getMoney());
                    //用户反水比例
                    double userIncome = userAgencyMap.get(rebate.getAgencyMark()).getUserIncome();
                    double money = DealWithDouble.mul(rebate.getMoney(),userIncome, 2, 4);
                    if (money == 0) {
                        logger.info("rebate is zero");
                        continue;
                    }
                    int userId = rebate.getUserId();
                    // 添加金额
                    Account account = accountdao.selectAccountByUserId(userId);
                    double sum = DealWithDouble.sum(account.getAccountFunds(), money, 2, 4);
                    account.setAccountFunds(sum);
                    accountdao.updateAccountById(account);
                    // 返点金额账户流水
                    AccountTransactionDto accountTransactionDto = new AccountTransactionDto();
                    accountTransactionDto.setUserId(userId);
                    accountTransactionDto.setOrderId(RandCodeUtil.getOrderId());
                    accountTransactionDto.setMoneySources("反水");
                    accountTransactionDto.setCashAccount(account.getAccountFunds());

                    String remark = DateUtil.getFormatDate(new Date(), "MM.dd") + "流水" + money
                            + "返水"+userIncome*100+"%";
                    accountTransactionDto.setRemarks(remark);
                    accountTransactionDto.setTransactionMoney(money);
                    accountTransactionDto.setTransactionType(7);
                    accountTransactionDto.setState(1);
                    accountTransactionDto.setFee(userIncome);
                    accountTransactionDto.setMoney(rebate.getMoney());
                    accountTransactionDto.setCashAccount(sum);
                    withdrawalsService.insertAccountTransactionDto(accountTransactionDto);



                    //代理商收益
                    Agency agency = proxyAgencyMap.get(rebate.getAgencyMark());
                    if(agency != null  && rebate.getRebateDone() == 0){
                        Account account1 = accountdao.selectAccountByUserId(agency.getUserId());
                        double platformDivisionMoney = DealWithDouble.mul(rebate.getMoney(),agency.getAgencyIncome(),4,4);
                        AccountTransaction accounttransaction = new AccountTransaction();
                        accounttransaction.setAccountId(account1.getId());
                        accounttransaction.setTransactionMoney(DealWithDouble.sum(platformDivisionMoney,0,2,4));
                        accounttransaction.setTransactionType(8);
                        accounttransaction.setTransactionDate(new Date());
                        accounttransaction.setMoneySources("代理商收益");
                        accounttransaction.setState(1);
                        accounttransaction.setOrderId(RandCodeUtil.getOrderId());
                        accounttransactionDao.insertAccountTransaction(accounttransaction);
                        account1.setAccountFunds(DealWithDouble.sum(account1.getAccountFunds(), platformDivisionMoney, 2, 4));
                        accountdao.updateAccountById(account1);

                        agency.setCommission(DealWithDouble.sum(agency.getCommission(),platformDivisionMoney,2,4));
                        agencydao.updateAgencyCommission(agency);

                    }
                }

                pageNow++;
            }
            bettinginfoDao.updateBetRobackStateYesterday(list);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("RebateService error", e);
            throw new Exception("平台返点失败");
        }
    }

    // 心跳包

    public String heartbeat(int serverId, String deviceId) {
        JSONObject jObject = new JSONObject();
        // 覆盖用户的时间戳
        onlineMap.put(serverId, (int) (System.currentTimeMillis() / 1000));
        String did = InitData.SSO_MAP.get(serverId);
        if (did != null && !deviceId.equals(did)) {
            logger.info("{}--{}", deviceId, did);
            jObject.put("result", "1");
            jObject.put("msg", "用户在其他地方登录，强行退出登录");
        } else {
            jObject.put("result", "0");
            jObject.put("msg", "成功");
        }

        return jObject.toString();
    }
}
